//
//  JSTAlertView.m
//  KYKJPackDemo
//
//  Created by 01 on 17/4/28.
//  Copyright © 2017年 ???. All rights reserved.
//

#import "JSTAlertView.h"
#import "UIImage-Extensions.h"
#define kContentLabelWidth      250.0f
static CGFloat kTransitionDuration = 0.3f;
static NSMutableArray *gAlertViewStack = nil;
static UIWindow *gPreviouseKeyWindow = nil;
static UIWindow *gMaskWindow = nil;

@interface JSTAlertView ()
{
    NSInteger clickedButtonIndex;
}

@property (nonatomic, strong) UITextView *bodyTextView;
@property (nonatomic, strong) UIView *customView;
@property (nonatomic, strong) UIButton *cancelButton;
@property (nonatomic, strong) UIButton *otherButton;

- (void)removeObservers;
- (BOOL)shouldRotateToOrientation:(UIInterfaceOrientation)orientation;
- (void)sizeToFitOrientation:(BOOL)transform;
- (CGAffineTransform)transformForOrientation;

+ (JSTAlertView *)getStackTopAlertView;
+ (void)pushAlertViewInStack:(JSTAlertView *)alertView;
+ (void)popAlertViewFromStack;

+ (void)presentMaskWindow;
+ (void)dismissMaskWindow;

+ (void)addAlertViewOnMaskWindow:(JSTAlertView *)alertView;
+ (void)removeAlertViewFormMaskWindow:(JSTAlertView *)alertView;

- (void)bounce0Animation;
- (void)bounce1AnimationDidStop;
- (void)bounce2AnimationDidStop;
- (void)bounceDidStop;

- (void)dismissAlertView;

+ (CGFloat)heightOfString:(NSString *)message;

@end

@implementation JSTAlertView

@synthesize delegate = _delegate;
@synthesize visible = _visible;
@synthesize dimBackground = _dimBackground;
@synthesize titleLabel = _titleLabel;
@synthesize bodyTextLabel = _bodyTextLabel;
@synthesize bodyTextView = _bodyTextView;
@synthesize customView = _customView;
@synthesize backgroundView = _backgroundView;
@synthesize contentView = _contentView;
@synthesize cancelButton = _cancelButton;
@synthesize otherButton = _otherButton;
@synthesize shouldDismissAfterConfirm = _shouldDismissAfterConfirm;
@synthesize contentAlignment = _contentAlignment;


- (void)dealloc {
    _delegate = nil;
    _cancelBlock = nil;
    _confirmBlock = nil;
    [self removeObserver:self forKeyPath:@"dimBackground"];
    [self removeObserver:self forKeyPath:@"contentAlignment"];
}

- (void)initData
{
    _shouldDismissAfterConfirm = YES;
    _dimBackground = YES;
    self.backgroundColor = [UIColor clearColor];
    _contentAlignment = NSTextAlignmentCenter;
    
    [self addObserver:self
           forKeyPath:@"dimBackground"
              options:NSKeyValueObservingOptionNew
              context:NULL];
    
    [self addObserver:self
           forKeyPath:@"contentAlignment"
              options:NSKeyValueObservingOptionNew
              context:NULL];
}

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{
    if ([keyPath isEqualToString:@"dimBackground"]) {
        [self setNeedsDisplay];
    }else if ([keyPath isEqualToString:@"contentAlignment"]){
        self.bodyTextLabel.textAlignment = self.contentAlignment;
        self.bodyTextView.textAlignment = self.contentAlignment;
    }
}

- (id)initWithTitle:(NSString *)title
            message:(NSString *)message
         customView:(UIView *)customView
           delegate:(id <JSTAlertViewDelegate>)delegate
  cancelButtonTitle:(NSString *)cancelButtonTitle
  otherButtonTitles:(NSString *)otherButtonTitle;
{
    self = [super initWithFrame:[UIScreen mainScreen].bounds];
    if (self) {
        [self initData];
        
        _delegate = delegate;
        
        CGFloat titleHeight = 23.0f;
        
        CGFloat bodyHeight;
        if (IsStrEmpty(message))
        {
            bodyHeight = 10;
        }
        else
        {
            bodyHeight = [JSTAlertView heightOfString:message]+ 10;
        }
        
        CGFloat customViewHeight = 0.0f;
        if (customView) {
            self.customView = customView;
            customViewHeight = customView.height;
        }
        CGFloat buttonPartHeight = 50.0f;
        
        BOOL isNeedUserTextView = bodyHeight > 170;
        bodyHeight = isNeedUserTextView?170:bodyHeight;
        
        CGFloat finalHeight = titleHeight+bodyHeight+customViewHeight+buttonPartHeight+10;
        
        CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height-20;
        self.contentView.frame = CGRectMake(10, (screenHeight-finalHeight)/2.0, 300, finalHeight);
        self.contentView.backgroundColor= [UIColor clearColor];
        
        //background image view
        UIImageView *bgImView = [[UIImageView alloc] init];
        bgImView.frame = CGRectMake(0, 0, 300, finalHeight);
        bgImView.image = [UIImage imageNamed:@"SNalert_bg"];
        [self.contentView addSubview:bgImView];
        
        //titleLabel
        UIFont *titleFont = [UIFont boldSystemFontOfSize:18.0f];
        CGSize size = CGSizeMake(kDeviceWidth, 20000.0f);
        NSDictionary * tdic = [NSDictionary dictionaryWithObjectsAndKeys:titleFont, NSFontAttributeName,nil];
        CGSize titleSize =[title boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin |NSStringDrawingUsesFontLeading attributes:tdic context:nil].size;
        
        CGFloat titleWidth = titleSize.width<240?titleSize.width:240;
        self.titleLabel.text = title;
        self.titleLabel.font = titleFont;
        self.titleLabel.adjustsFontSizeToFitWidth = YES;
        CGFloat orgionX = 5+(240-titleWidth)/2+20;
        self.titleLabel.frame = CGRectMake(orgionX, 10, titleWidth, titleHeight-10 + 10);
        [self.contentView addSubview:self.titleLabel];
        
        //bodyLabel
        if (isNeedUserTextView) {
            self.bodyTextView.text = message;
            self.bodyTextView.textColor = [UIColor colorWithRed:17/255.0 green:17/255.0 blue:17/255.0 alpha:1.0f];
            self.bodyTextView.font = [UIFont fontWithName:@"STHeitiSC-Light" size:15.0f];
            self.bodyTextView.textAlignment = NSTextAlignmentLeft;
            self.bodyTextView.frame = CGRectMake(18, titleHeight, 264, bodyHeight);
            self.bodyTextView.font = [UIFont systemFontOfSize:16.0f];
            [self.contentView addSubview:self.bodyTextView];
        }
        else
        {
            self.bodyTextLabel.text = message;
            self.bodyTextView.textColor = [UIColor colorWithRed:17/255.0 green:17/255.0 blue:17/255.0 alpha:1.0f];
            self.bodyTextView.font = [UIFont fontWithName:@"STHeitiSC-Light" size:15.0f];
            self.bodyTextLabel.frame = CGRectMake(18, titleHeight, 264, bodyHeight);
            self.bodyTextLabel.font = [UIFont systemFontOfSize:16.0f];
            [self.contentView addSubview:self.bodyTextLabel];
        }
        
        //custom view
        if (customView) {
            customView.frame = CGRectMake(0, titleHeight+bodyHeight+5, customView.width, customView.height);
            [self.contentView addSubview:customView];
        }
        
        //buttons
        if (cancelButtonTitle && otherButtonTitle) {
            CGFloat buttonTopPosition = titleHeight+bodyHeight+customViewHeight+23;
            [self.cancelButton setBackgroundImage:[UIImage streImageNamed:@"SNAlertButton_left"] forState:UIControlStateNormal];
            [self.cancelButton setBackgroundImage:[UIImage streImageNamed:@"SNAlertButton_left"] forState:UIControlStateHighlighted];
            [self.cancelButton setTitle:cancelButtonTitle?cancelButtonTitle:otherButtonTitle forState:UIControlStateNormal];
            [self.cancelButton setTitleColor:kSPBlackTextColor forState:UIControlStateNormal];
            self.cancelButton.titleLabel.font = [UIFont fontWithName:@"STHeitiSC-Medium" size:17.0f];
            [self.cancelButton setFrame:CGRectMake(0, buttonTopPosition, 150, 44)];
            
            
            [self.otherButton setBackgroundImage:[UIImage streImageNamed:@"SNAlertButton_right"] forState:UIControlStateNormal];
            [self.otherButton setBackgroundImage:[UIImage streImageNamed:@"SNAlertButton_right"] forState:UIControlStateHighlighted];
            [self.otherButton setTitle:otherButtonTitle forState:UIControlStateNormal];
            [self.otherButton setTitleColor:kSPBlackTextColor forState:UIControlStateNormal];
            self.otherButton.titleLabel.font = [UIFont fontWithName:@"STHeitiSC-Medium" size:17.0f];
            [self.otherButton setFrame:CGRectMake(self.cancelButton.right, buttonTopPosition, 150, 44)];
            
            [self.cancelButton setTag:0];
            [self.otherButton setTag:1];
            
            [self.contentView addSubview:self.cancelButton];
            [self.contentView addSubview:self.otherButton];
            
        }
        else if (cancelButtonTitle)
        {
            CGFloat buttonTopPosition = titleHeight+bodyHeight+customViewHeight+23;
            [self.cancelButton setBackgroundImage:[UIImage imageNamed:@"SNalert_do_button"] forState:UIControlStateNormal];
            [self.cancelButton setBackgroundImage:[UIImage imageNamed:@"SNalert_do_pressed"] forState:UIControlStateHighlighted];
            [self.cancelButton setTitle:cancelButtonTitle?cancelButtonTitle:otherButtonTitle forState:UIControlStateNormal];
            [self.cancelButton setTitleColor:kSPBlackTextColor forState:UIControlStateNormal];
            self.cancelButton.titleLabel.font = [UIFont fontWithName:@"STHeitiSC-Medium" size:17.0f];
            [self.cancelButton setFrame:CGRectMake(0, buttonTopPosition, 300, 44)];
            [self.cancelButton setTag:0];
            [self.contentView addSubview:self.cancelButton];
        }
        else if (otherButtonTitle)
        {
            CGFloat buttonTopPosition = titleHeight+bodyHeight+customViewHeight+23;
            [self.otherButton setBackgroundImage:[UIImage imageNamed:@"SNalert_do_button"] forState:UIControlStateNormal];
            [self.otherButton setBackgroundImage:[UIImage imageNamed:@"SNalert_do_pressed"] forState:UIControlStateHighlighted];
            [self.otherButton setTitle:cancelButtonTitle?cancelButtonTitle:otherButtonTitle forState:UIControlStateNormal];
            [self.otherButton setTitleColor:kSPBlackTextColor forState:UIControlStateNormal];
            self.otherButton.titleLabel.font = [UIFont fontWithName:@"STHeitiSC-Medium" size:17.0f];
            [self.otherButton setFrame:CGRectMake(0, buttonTopPosition, 300, 44)];
            [self.otherButton setTag:0];
            [self.contentView addSubview:self.otherButton];
            
        }
    }
    return [super initWithFrame:[UIScreen mainScreen].bounds];
}

- (BOOL)isVisible
{
    return _visible;
}

- (void)drawRect:(CGRect)rect
{
    if (_dimBackground) {
        CGContextRef context = UIGraphicsGetCurrentContext();
        
        size_t gradLocationsNum = 2;
        CGFloat gradLocations[2] = {0.0f, 1.0f};
        CGFloat gradColors[8] = {0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.4f};
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, gradColors, gradLocations, gradLocationsNum);
        CGColorSpaceRelease(colorSpace);
        
        //Gradient center
        CGPoint gradCenter = self.contentView.center;
        //Gradient radius
        float gradRadius = 10 ;
        //Gradient draw
        CGContextDrawRadialGradient (context, gradient, gradCenter,
                                     0, gradCenter, gradRadius,
                                     kCGGradientDrawsAfterEndLocation);
        CGGradientRelease(gradient);
    }
}

#pragma mark -
#pragma mark orientation

- (void)registerObservers{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationDidChange:) name:UIDeviceOrientationDidChangeNotification object:nil];
}

- (void)removeObservers{
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
}

- (void)orientationDidChange:(NSNotification*)notify
{
    
    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
    if ([self shouldRotateToOrientation:orientation]) {
        if ([_delegate respondsToSelector:@selector(didRotationToInterfaceOrientation:view:alertView:)]) {
            [_delegate didRotationToInterfaceOrientation:UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation) view:_customView alertView:self];
        }
        [UIView beginAnimations:nil context:nil];
        [UIView setAnimationDuration:0.25f];
        [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
        [UIView setAnimationBeginsFromCurrentState:YES];
        [self sizeToFitOrientation:YES];
        [UIView commitAnimations];
    }
}

- (BOOL)shouldRotateToOrientation:(UIInterfaceOrientation)orientation
{
    BOOL result = NO;
    if (_orientation != orientation) {
        result = (orientation == UIInterfaceOrientationPortrait ||
                  orientation == UIInterfaceOrientationPortraitUpsideDown ||
                  orientation == UIInterfaceOrientationLandscapeLeft ||
                  orientation == UIInterfaceOrientationLandscapeRight);
    }
    
    return result;
}

- (void)sizeToFitOrientation:(BOOL)transform
{
    if (transform) {
        self.transform = CGAffineTransformIdentity;
    }
    _orientation = [UIApplication sharedApplication].statusBarOrientation;
    [self sizeToFit];
    CGSize screenSize = [UIScreen mainScreen].bounds.size;
    [self setCenter:CGPointMake(screenSize.width/2, screenSize.height/2)];
    if (transform) {
        self.transform = [self transformForOrientation];
    }
}

- (CGAffineTransform)transformForOrientation
{
    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
    if (orientation == UIInterfaceOrientationLandscapeLeft) {
        return CGAffineTransformMakeRotation(M_PI*1.5f);
    } else if (orientation == UIInterfaceOrientationLandscapeRight) {
        return CGAffineTransformMakeRotation(M_PI/2.0f);
    } else if (orientation == UIInterfaceOrientationPortraitUpsideDown) {
        return CGAffineTransformMakeRotation(-M_PI);
    } else {
        return CGAffineTransformIdentity;
    }
}


#pragma mark -
#pragma mark view getters

- (UILabel *)titleLabel
{
    if (!_titleLabel) {
        _titleLabel = [[UILabel alloc] init];
        _titleLabel.textAlignment = NSTextAlignmentCenter;
        _titleLabel.backgroundColor = [UIColor clearColor];
    }
    return _titleLabel;
}

- (UILabel *)bodyTextLabel
{
    if (!_bodyTextLabel) {
        _bodyTextLabel = [[UILabel alloc] init];
        _bodyTextLabel.numberOfLines = 0;
        _bodyTextLabel.lineBreakMode = NSLineBreakByCharWrapping;
        _bodyTextLabel.textAlignment = _contentAlignment;
        _bodyTextLabel.backgroundColor = [UIColor clearColor];
    }
    return _bodyTextLabel;
}

- (UITextView *)bodyTextView
{
    if (!_bodyTextView) {
        _bodyTextView = [[UITextView alloc] init];
        _bodyTextView.textAlignment = _contentAlignment;
        _bodyTextView.bounces = NO;
        _bodyTextView.backgroundColor = [UIColor clearColor];
        _bodyTextView.editable = NO;
    }
    return _bodyTextView;
}

- (UIView *)contentView
{
    if (!_contentView) {
        _contentView = [[UIView alloc] init];
        [self addSubview:_contentView];
    }
    return _contentView;
}

- (UIButton *)cancelButton{
    
    if (!_cancelButton) {
        _cancelButton = [UIButton buttonWithType:UIButtonTypeCustom];
        [_cancelButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
        [_cancelButton setTitle:@"确定" forState:UIControlStateNormal];
        [_cancelButton addTarget:self action:@selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
    }
    return _cancelButton;
    
}


- (UIButton *)otherButton{
    
    if (!_otherButton) {
        _otherButton = [UIButton buttonWithType:UIButtonTypeCustom];
        [_otherButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
        [_otherButton setTitle:@"确定" forState:UIControlStateNormal];
        [_otherButton addTarget:self action:@selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
    }
    
    return _otherButton;
    
}

#pragma mark -
#pragma mark block setter

- (void)setCancelBlock:(JSTBasicBlock)block
{
    _cancelBlock = [block copy];
}

- (void)setConfirmBlock:(JSTBasicBlock)block
{
    _confirmBlock = [block copy];
}

#pragma mark -
#pragma mark button action

- (void)buttonTapped:(id)sender
{
    UIButton *button = (UIButton *)sender;
    NSInteger tag = button.tag;
    clickedButtonIndex = tag;
    
    if ([_delegate conformsToProtocol:@protocol(JSTAlertViewDelegate)]) {
        
        if ([_delegate respondsToSelector:@selector(alertView:willDismissWithButtonIndex:)]) {
            
            [_delegate alertView:self willDismissWithButtonIndex:tag];
        }
    }
    
    if (button == self.cancelButton) {
        if (_cancelBlock) {
            _cancelBlock();
        }
        [self dismiss];
    }
    else if (button == self.otherButton)
    {
        if (_confirmBlock) {
            _confirmBlock();
        }
        if (_shouldDismissAfterConfirm) {
            [self dismiss];
        }
    }
}

#pragma mark -
#pragma mark lify cycle

- (void)show
{
    if (_visible) {
        return;
    }
    _visible = YES;
    
    [self registerObservers];//添加消息，在设备发生旋转时会有相应的处理
    [self sizeToFitOrientation:NO];
    
    
    //如果栈中没有alertview,就表示maskWindow没有弹出，所以弹出maskWindow
    if (![JSTAlertView getStackTopAlertView]) {
        [JSTAlertView presentMaskWindow];
    }
    
    //如果有背景图片，添加背景图片
    if (nil != self.backgroundView && ![[gMaskWindow subviews] containsObject:self.backgroundView]) {
        [gMaskWindow addSubview:self.backgroundView];
    }
    //将alertView显示在window上
    [JSTAlertView addAlertViewOnMaskWindow:self];
    
    self.alpha = 1.0;
    [self.contentView setCenterX:[UIScreen mainScreen].bounds.size.width/2];
    //alertView弹出动画
    [self bounce0Animation];
}

- (void)dismiss
{
    if (!_visible) {
        return;
    }
    _visible = NO;
    
    UIView *__bgView = self->_backgroundView;
    
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:kTransitionDuration];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(dismissAlertView)];
    self.alpha = 0;
    [UIView commitAnimations];
    
    if (__bgView && [[gMaskWindow subviews] containsObject:__bgView]) {
        [__bgView removeFromSuperview];
    }
}

- (void)dismissAlertView{
    [JSTAlertView removeAlertViewFormMaskWindow:self];
    
    // If there are no dialogs visible, dissmiss mask window too.
    if (![JSTAlertView getStackTopAlertView]) {
        [JSTAlertView dismissMaskWindow];
    }
    
    if ([_delegate conformsToProtocol:@protocol(JSTAlertViewDelegate)]) {
        if ([_delegate respondsToSelector:@selector(alertView:didDismissWithButtonIndex:)]) {
            [_delegate alertView:self didDismissWithButtonIndex:clickedButtonIndex];
        }
    }
    [self removeObservers];
}

+ (void)dismissAllAlerts
{
    for (JSTAlertView *alert in gAlertViewStack)
    {
        if ( alert.visible) {
            [alert setDelegate:nil];
            [alert dismiss];
        }
    }
}

+ (void)presentMaskWindow{
    
    if (!gMaskWindow) {
        gMaskWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
        gMaskWindow.windowLevel =UIWindowLevelAlert;
        gMaskWindow.backgroundColor = [UIColor clearColor];
        gMaskWindow.hidden = YES;
        
        // FIXME: window at index 0 is not awalys previous key window.
        gPreviouseKeyWindow = [[UIApplication sharedApplication].windows objectAtIndex:0];
        [gMaskWindow makeKeyAndVisible];
        
        // Fade in background
        gMaskWindow.alpha = 0;
        [UIView beginAnimations:nil context:nil];
        [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
        gMaskWindow.alpha = 1;
        [UIView commitAnimations];
    }
}

+ (void)dismissMaskWindow{
    // make previouse window the key again
    if (gMaskWindow) {
        [gPreviouseKeyWindow makeKeyAndVisible];
         gPreviouseKeyWindow = nil;
        
        gMaskWindow = nil;
    }
}

+ (JSTAlertView *)getStackTopAlertView{
    JSTAlertView *topItem = nil;
    if (0 != [gAlertViewStack count]) {
        topItem = [gAlertViewStack lastObject];
    }
    
    return topItem;
}

+ (void)addAlertViewOnMaskWindow:(JSTAlertView *)alertView{
    if (!gMaskWindow ||[gMaskWindow.subviews containsObject:alertView]) {
        return;
    }
    
    [gMaskWindow addSubview:alertView];
    alertView.hidden = NO;
    
    JSTAlertView *previousAlertView = [JSTAlertView getStackTopAlertView];
    if (previousAlertView) {
        previousAlertView.hidden = YES;
    }
    [JSTAlertView pushAlertViewInStack:alertView];
}

+ (void)removeAlertViewFormMaskWindow:(JSTAlertView *)alertView{
    if (!gMaskWindow || ![gMaskWindow.subviews containsObject:alertView]) {
        return;
    }
    
    [alertView removeFromSuperview];
    alertView.hidden = YES;
    
    [JSTAlertView popAlertViewFromStack];
    JSTAlertView *previousAlertView = [JSTAlertView getStackTopAlertView];
    if (previousAlertView) {
        previousAlertView.hidden = NO;
        [previousAlertView bounce0Animation];
    }
}

+ (void)pushAlertViewInStack:(JSTAlertView *)alertView{
    if (!gAlertViewStack) {
        gAlertViewStack = [[NSMutableArray alloc] init];
    }
    [gAlertViewStack addObject:alertView];
}


+ (void)popAlertViewFromStack{
    if (![gAlertViewStack count]) {
        return;
    }
    [gAlertViewStack removeLastObject];
    
    if ([gAlertViewStack count] == 0) {
        gAlertViewStack = nil;
    }
}


#pragma mark -
#pragma mark animation

- (void)bounce0Animation{
    self.contentView.transform = CGAffineTransformScale([self transformForOrientation], 0.001f, 0.001f);
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:kTransitionDuration/1.5f];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(bounce1AnimationDidStop)];
    self.contentView.transform = CGAffineTransformScale([self transformForOrientation], 1.1f, 1.1f);
    [UIView commitAnimations];
}

- (void)bounce1AnimationDidStop{
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:kTransitionDuration/2];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(bounce2AnimationDidStop)];
    self.contentView.transform = CGAffineTransformScale([self transformForOrientation], 0.9f, 0.9f);
    [UIView commitAnimations];
}
- (void)bounce2AnimationDidStop{
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:kTransitionDuration/2];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(bounceDidStop)];
    self.contentView.transform = [self transformForOrientation];
    [UIView commitAnimations];
}

- (void)bounceDidStop{
    
}

#pragma mark -
#pragma mark tools

+ (CGFloat)heightOfString:(NSString *)message
{
    if (IsStrEmpty(message))
    {
        return 20.0f;
    }
    
    UIFont *font = [UIFont systemFontOfSize:16.0];
    
    CGSize size = CGSizeMake(kContentLabelWidth, 20000.0f);
    NSDictionary * tdic = [NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName,nil];
    CGSize messageSize =[message boundingRectWithSize:size
                                              options:NSStringDrawingUsesLineFragmentOrigin |NSStringDrawingUsesFontLeading
                                           attributes:tdic context:nil].size;
    
    return messageSize.height+10.0;
}

@end
